/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.model.codes;

import java.nio.charset.Charset;

import org.zhiqim.kernel.annotation.AnAlias;
import org.zhiqim.kernel.constants.CodeConstants;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Validates;

/**
 * Base64编解码，根据BASE64的定义重写了方法，具体见Base64Encoder/Base64Decoder类
 * 1、编码时返回的字符串无需指定字符集，但编码前的字符串需要
 * 2、解码时原字符串无需指定字符集，但解码后的字符串需要
 * 
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 */
@AnAlias("Base64")
public class Base64 implements CodeConstants
{
    /*************************************************************************************************/
    //标准编解码
    /*************************************************************************************************/
    
    /** 把字节数组编码成字符串 */
    public static String encode(byte[] src)
    {
        Asserts.notNull(src);
        return new String(Base64Encoder.encode(src), _UTF_8_C_);
    }
    
    
    /** 把字符串解码成字节数组 */
    public static byte[] decode(String src)
    {
        Asserts.notNull(src, _SRC_);
        Asserts.as(Validates.isScope(src, _BASE64_EXT_)?null:"参数含有不是Base64字符串允许的字符");
        
        return Base64Decoder.decode(src.getBytes(_UTF_8_C_));
    }
    
    /*************************************************************************************************/
    //指定UTF-8编码的字符串编解码
    /*************************************************************************************************/
    
    /** 使用UTF-8进行Base64编码 */
    public static String encodeUTF8(String src)
    {
        return encode(src, _UTF_8_C_);
    }
    
    /** 使用UTF-8进行Base64解码 */
    public static String decodeUTF8(String src)
    {
        return decode(src, _UTF_8_C_);
    }
    
    /*************************************************************************************************/
    //指定${字符集}的字符串编解码
    /*************************************************************************************************/
    
    /** 使用指定编码格式进行Base64编码 */
    public static String encode(String src, String encoding)
    {
        return encode(src, Charset.forName(encoding));
    }
    
    /** 使用指定编编码进行Base64编码 */
    public static String encode(String src, Charset charset)
    {
        return encode(src.getBytes(charset));
    }
    
    /** 指定编码格式进行Base64解码 */
    public static String decode(String src, String encoding)
    {
        return decode(src, Charset.forName(encoding));
    }
    
    /** 指定字符集进行Base64解码 */
    public static String decode(String src, Charset charset)
    {
        return new String(decode(src), charset);
    }
    
    /*************************************************************************************************/
    //文件名编解码
    /*************************************************************************************************/
    
    /** 使用UTF-8进行Base64编码，并替换+为-，/替换成_ */
    public static String encodeFileUrlUTF8(String src)
    {
        return encode(src, _UTF_8_C_).replaceAll("\\+", "~").replaceAll("/", "_");
    }
    
    /** 使用UTF-8进行Base64解码，并替换+为-，/替换成_ */
    public static String decodeFileUrlUTF8(String src)
    {
        return decode(src.replaceAll("~", "\\+").replaceAll("_", "/"), _UTF_8_C_);
    }

    /*************************************************************************************************/
    //URL编解码
    /*************************************************************************************************/
    
    /** 使用UTF-8进行Base64编码，并替换/为_ */
    public static String encodeFileNameUTF8(String src)
    {
        return encode(src, _UTF_8_C_).replaceAll("/", "_");
    }
    
    /** 使用UTF-8进行Base64解码，并替换/为_ */
    public static String decodeFileNameUTF8(String src)
    {
        return decode(src.replaceAll("_", "/"), _UTF_8_C_);
    }
}
